#pragma once

#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

#include "ArmorBase.h"
#include "ArmorAssembler.h"
#include "BarDetector.h"
#include  "../basic/Frame.h"
namespace hitcrt {

class ArmorDetectorBase {
   public:
    virtual bool detect(const Frame& frame, const Color color, const ROI& roi, BarDetectorBase& barDetector,
                        ArmorAssemblerBase& assembler, std::vector<Armor>& armors) = 0;
    ArmorDetectorBase() = default;
    ArmorDetectorBase(const int binaryThreshold) : m_binaryThreshold(binaryThreshold) {}

    // setters
    // 二值化阈值调整
    void setBinaryThresh(const int value) { m_binaryThreshold = value; };
    // getters
    const int binaryThresh() const { return m_binaryThreshold; };
    const cv::Mat& getSrcImg() const { return m_srcImg; };
    const cv::Mat& getRoiImg() const { return m_roiImg; };
    const cv::Mat& getEnemyChannel() const { return m_enemyChannel; };
    const cv::Mat& getSelfChannel() const { return m_selfChannel; };
    const cv::Mat& getBinImg() const { return m_binImg; };
    cv::Mat m_srcImg;                 // 指针
    cv::Mat m_roiImg;                 // 实际存
    cv::Mat m_enemyChannel;           //
    cv::Mat m_selfChannel;            //
    cv::Mat m_binImg;                 // 实际存
    std::vector<cv::Mat> m_channels;  // 实际存
    
    int m_binaryThreshold;  // 二值化阈值
};

class ArmorDetector final : public ArmorDetectorBase {
   public:
    // 预处理
    ArmorDetector(const int binaryThreshold) : ArmorDetectorBase(binaryThreshold) {}
    bool detect(const Frame& frame, const Color color, const ROI& roi, BarDetectorBase& barDetector,
                ArmorAssemblerBase& assembler, std::vector<Armor>& armors) override;
    bool preProcess(const Color color, const cv::Mat& srcImg);
};
}  // namespace hitcrt
